package uk.ac.imperial.gpaexpress.client;

import java.util.Date;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.Element;
import com.google.gwt.xml.client.NodeList;
import com.google.gwt.xml.client.XMLParser;

public class LoginScreen extends Composite {

	private static LoginScreenUiBinder uiBinder = GWT.create(LoginScreenUiBinder.class);
	interface LoginScreenUiBinder extends UiBinder<Widget, LoginScreen> {}

	@UiField VerticalPanel loginScreen;
	@UiField Button loginButton;
	@UiField TextBox userText;
	@UiField PasswordTextBox passwordText;
	@UiField CheckBox registerCheck;
	@UiField Label loginErrorLabel;
	
	UserInterface ui;
	
	@UiHandler("loginButton")
	void loginClick(ClickEvent e) {
		try {
			login();
		} catch (RequestException e1) {
			e1.printStackTrace();
		}
	}
	
	@UiHandler("passwordText")
	void onKeyUp(KeyUpEvent event){
		if(event.getNativeKeyCode()==KeyCodes.KEY_ENTER){
			try {
				login();
			} catch (RequestException e) {
				e.printStackTrace();
			}
		}
	}
	
	public LoginScreen(UserInterface ui) {
		initWidget(uiBinder.createAndBindUi(this));
		this.ui = ui;
		userText.getElement().setAttribute("spellCheck", "false");
		passwordText.getElement().setAttribute("spellCheck", "false");
	}

	/* method logs in by sending text and password values to loginServlet */
	private void login() throws RequestException {
		if(userText.getText().equals("")){
			loginErrorLabel.setText("Please enter email address.");
			return;
		}else if(passwordText.getText().equals("")){
			loginErrorLabel.setText("Please enter password");
			return;
		}
		loginErrorLabel.setText("");
		RequestBuilder loginRequest = new RequestBuilder(RequestBuilder.POST,"/Login");
		String type;
		if(registerCheck.getValue()==true){
			type = "register";
		}else{
			type = "login";
		}
		loginRequest.setHeader("type", type);
		loginRequest.setHeader("email", userText.getText());
		loginRequest.setHeader("password", passwordText.getText());
		loginRequest.sendRequest(null, new RequestCallback(){
			public void onResponseReceived(Request request, Response response) {
				if(response.getText().equals("email_fail")){
					userText.setText("");
					passwordText.setText("");
					loginErrorLabel.setText("Email address not registered.");
				}else if(response.getText().equals("password_fail")){
					passwordText.setText("");
					loginErrorLabel.setText("Password incorrect.");
				}else if(response.getText().equals("email_taken")){
					userText.setText("");
					passwordText.setText("");
					loginErrorLabel.setText("Email address already registered.");
				}else{
					ui.loggedIn = true;
					populateInterface(response.getText());
					PopupPanel parent = (PopupPanel) loginScreen.getParent().getParent();
					parent.hide();
				}

			}
			public void onError(Request request, Throwable exception) {
			}
		});
	}

	/* method populates interface using information returned from loginServlet */
	private void populateInterface(String xmlString){
		try{
			Document dom = XMLParser.parse(xmlString);
			
			//get username
			Element userElement = (Element) (dom.getElementsByTagName("user")).item(0);
			ui.userEmail.setText(userElement.getAttribute("email"));
			
			//show logout anchor
			ui.logoutAnchor.setText("(logout)");
			
			//get model nodes
			NodeList modelNodes = dom.getElementsByTagName("model");
			ui.modelList.addItem("");
			ui.paramList.addItem("");
			//loop through each model node
			for(int i = 0; i<modelNodes.getLength(); i++){
				Element em = (Element) modelNodes.item(i);
				ui.modelList.addItem(em.getAttribute("title") + " #" + em.getAttribute("id"));
			}
			ui.modelText.setFocus(true);
			ui.tickerStart();
			final DateTimeFormat dateTimeFormat = DateTimeFormat.getFormat("MMM dd HH:mm:ss");
			final String dateTime = dateTimeFormat.format(new Date());
			Notification loginNote = new Notification(dateTime, "Current session started.");
			ui.notificationPanel.add(loginNote);
			NodeList notificationNodes = dom.getElementsByTagName("notification");
			for(int i = 0; i<notificationNodes.getLength(); i++){
				Element em = (Element) notificationNodes.item(i);
				Notification note = new Notification(em.getAttribute("timestamp"),em.getAttribute("message"));
				ui.notificationPanel.add(note);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
